package com.kingsoft.dc.khaos.module.spark.util

import com.kingsoft.dc.khaos.KhaosContext
import com.kingsoft.dc.khaos.extender.meta.api.{AuthRequest, CmReportResult, CmRequest}
import com.kingsoft.dc.khaos.extender.meta.utils.{CmReportUtils, DmMetaUtils}
import com.kingsoft.dc.khaos.module.spark.constants.SchedulerConstants
import com.kingsoft.dc.khaos.module.spark.model.center.metric.{CosProcessDataMetric, DataMetric, SyncProcessDataMetric}
import com.kingsoft.dc.khaos.module.spark.util.CenterMetricUtils.{buildCmRequest, buildCommonDataMetric}
import com.kingsoft.dc.khaos.util.Logging

/**
  * Created by haorenhui on 2020/11/03.
  * 运维中心-指标上报
  */
object CenterMetricUtils extends Logging {

  def buildCmRequest(rearUrl: String, authUrl: String): CmRequest = {
    val request = new CmRequest()
    request.setUrl(rearUrl)
    val authRequest: AuthRequest = new AuthRequest()
    authRequest.setAuthUrl(authUrl)
    request.setAuthRequest(authRequest)
    request
  }

  def buildReportSyncProcessDataRequest(rearUrl: String, authUrl: String): CmRequest = {
    val request = new CmRequest()
    request.setUrl(rearUrl)
    val authRequest: AuthRequest = new AuthRequest()
    authRequest.setAuthUrl(authUrl)
    request.setAuthRequest(authRequest)
    request
  }

  /**
    * 上报指标
    * 只上报online且syncTask的任务
    *
    * @param metric metric实体类
    * @return void
    */
  def reportSyncProcessData(metric: SyncProcessDataMetric, kc: KhaosContext): Unit = {
    try {
      val realUrl: String = kc.conf.getString(SchedulerConstants.OPS_SLA_REPORT_URL)
      val authUrl: String = kc.conf.getString(SchedulerConstants.AUTH_SERVER_KEY)
      val request: CmRequest = buildReportSyncProcessDataRequest(realUrl, authUrl)
      val jobType: String = metric.getJobType
      val env: String = metric.getEnv
      jobType match {
        case SchedulerConstants.SYNCTASK =>
          val metricJson: String = metric.toString
          println("reportSyncProcessData 运维中心指标 : " + metricJson)
          request.setParams(metricJson)
          val result: CmReportResult = CmReportUtils.reportSyncProcessData(request, classOf[CmReportResult])
          //返回结果
          if (result == null) {
            log.warn("reportSyncProcessData fail: result = null")
          } else if (result != null && result.getStatus != 200) {
            log.warn(String.format("reportSyncProcessData fail: status: %s, message: %s, error: %s, path: %s , timestamp: %s", result.getStatus.toString, result.getMessage, result.getError, result.getPath, result.getTimestamp))
          } else if (result != null && result.getStatus == 200) {
            log.info(String.format("reportSyncProcessData success: status: %s, message: %s ", result.getStatus.toString, result.getMessage))
          }
        case _ => log.info(s"reportSyncProcessData jobType:$jobType don't report")
      }
    } catch {
      case e: Exception =>
        log.error("reportSyncProcessData fail,运维中心指标上报失败", e)
    }
  }

  /**
    * 构建metric上报实体
    *
    * @param kc kc
    * @return SyncProcessDataMetric
    */
  def buildSyncProcessDataMetric(kc: KhaosContext): SyncProcessDataMetric = {
    val metric = new SyncProcessDataMetric
    metric.setEnv(kc.conf.getString(SchedulerConstants.RUN_ENV))
    metric.setFlowName(kc.conf.getString(SchedulerConstants.FLOW_NAME))
    metric.setFlowId(kc.conf.getString(SchedulerConstants.FLOW_ID))
    metric.setJobInstId(kc.conf.getString(SchedulerConstants.JOB_INSTANCE_ID))
    metric.setJobId(kc.conf.getString(SchedulerConstants.JOB_ID))
    metric.setJobName(kc.conf.getString(SchedulerConstants.JOB_NAME))
    metric.setJobType(kc.conf.getString(SchedulerConstants.JOB_TYPE))
    metric.setUserId(kc.conf.getString(SchedulerConstants.TENANT_ID))
    metric.setProjectId(kc.conf.getString(SchedulerConstants.PROJECT_ID))
    metric.setProjectName(kc.conf.getString(SchedulerConstants.PROJECT_NAME))

    val bizDate: String = kc.conf.getString(SchedulerConstants.BIZ_DATE)
    val bizTime: String = kc.conf.getString(SchedulerConstants.BIZ_TIME)
    val bizTimestamp: Long = DateUtils.getBizDateTimestamp(bizDate, bizTime)
    metric.setBizDate(bizDate)
    metric.setBizTime(bizTime)
    metric.setBizTimestamp(bizTimestamp)
    metric.setTimestamp(System.currentTimeMillis())
    metric
  }

  /**
    * 上报cos处理数据量指标
    * 只上报online且syncTask/dataProcess/offlineJar/python2/python3的任务
    * @param metric metric实体类
    * @return void
    */
  def reportCosProcessData(metric: CosProcessDataMetric,kc:KhaosContext): Unit ={
    try{
      val realUrl: String = kc.conf.getString(SchedulerConstants.OPS_SLA_REPORT_URL)
      val authUrl: String = kc.conf.getString(SchedulerConstants.AUTH_SERVER_KEY)
      val request: CmRequest = buildCmRequest(realUrl,authUrl)
      val jobType: String = metric.getJobType
      val env: String = metric.getEnv
      jobType match {
        case SchedulerConstants.SYNCTASK | SchedulerConstants.DATAPROCESS =>
          env match {
            case SchedulerConstants.ONLINE =>
              val metricJson: String = metric.toString
              println("reportCosProcessData 运维中心指标 : " + metricJson)
              request.setParams(metricJson)
              println("输出  "+request.toString)
              val result: CmReportResult = CmReportUtils.reportSyncProcessData(request, classOf[CmReportResult])
              //返回结果
              if (result == null) {
                log.warn("reportCosProcessData fail: result = null")
              } else if (result != null && result.getStatus != 200) {
                log.warn(String.format("reportCosProcessData fail: status: %s, message: %s, error: %s, path: %s , timestamp: %s", result.getStatus.toString, result.getMessage, result.getError, result.getPath, result.getTimestamp))
              } else if (result != null && result.getStatus == 200) {
                log.info(String.format("reportCosProcessData success: status: %s, message: %s ", result.getStatus.toString, result.getMessage))
              }
            case _ =>
              log.info(s"reportCosProcessData jobType:$jobType env:$env don't report")
          }
        case _ =>   log.info(s"reportCosProcessData jobType:$jobType don't report")
      }
    }catch{
      case e: Exception =>
        log.error("reportCosProcessData fail,运维中心指标上报失败",e)
    }
  }

    /**
      * 构建metric上报实体
      *
      * @param kc kc
      * @return SyncProcessDataMetric
      */
    def buildCosProcessDataMetric(kc: KhaosContext): CosProcessDataMetric = {
      val metric = new CosProcessDataMetric
      buildCommonDataMetric(metric, kc)
      metric
    }

    def buildCommonDataMetric[T <: DataMetric](metric: T, kc: KhaosContext): T = {
      metric.setEnv(kc.conf.getString(SchedulerConstants.RUN_ENV))
      metric.setFlowName(kc.conf.getString(SchedulerConstants.FLOW_NAME))
      metric.setFlowId(kc.conf.getString(SchedulerConstants.FLOW_ID))
      metric.setJobInstId(kc.conf.getString(SchedulerConstants.JOB_INSTANCE_ID))
      metric.setJobId(kc.conf.getString(SchedulerConstants.JOB_ID))
      metric.setJobName(kc.conf.getString(SchedulerConstants.JOB_NAME))
      metric.setJobType(kc.conf.getString(SchedulerConstants.JOB_TYPE))
      metric.setUserId(kc.conf.getString(SchedulerConstants.TENANT_ID))
      metric.setProjectId(kc.conf.getString(SchedulerConstants.PROJECT_ID))
      metric.setProjectName(kc.conf.getString(SchedulerConstants.PROJECT_NAME))

      val bizDate: String = kc.conf.getString(SchedulerConstants.BIZ_DATE)
      val bizTime: String = kc.conf.getString(SchedulerConstants.BIZ_TIME)
      val bizTimestamp: Long = DateUtils.getBizDateTimestamp(bizDate, bizTime)
      metric.setBizDate(bizDate)
      metric.setBizTime(bizTime)
      metric.setBizTimestamp(bizTimestamp)
      metric.setTimestamp(System.currentTimeMillis())
      metric
    }


}